package com.cx.auth.utils;

import com.cx.auth.enums.AuthorityEnum;
import com.cx.auth.feign.AuthService;
import com.cx.auth.model.LocalCache;
import com.cx.auth.model.vo.ResultBean;
import com.cx.auth.model.vo.UserDetailsVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author: zhangcx
 * @Description: 权限token公共类
 * @date: 2024/1/10 13:07
 * @email: zhangcx@bluemoon.com.cn
 */
@Slf4j
@Component
public class AuthTokenUtils {

    private static final NamedThreadLocal<UserDetailsVO> threadLocal = new NamedThreadLocal("StopWatch-UserInfo");
    private static final String KEY_PREF = "OAUTH_AUTH_:TOKEN_";
    private static AuthService authService;

    @Autowired
    private AuthService feignAuthService;

    @PostConstruct
    public void init() {
        authService = this.feignAuthService;
    }

    /**
     * 根据token校验用户信息
     * @param token
     */
    public static void validUserInfo(String token) {
        if (StringUtils.isBlank(token)){
            throw new RuntimeException(AuthorityEnum.TOKEN_NOT_BLANK.getMessage());
        }

        String key = KEY_PREF + token;
        UserDetailsVO userInfo = (UserDetailsVO) LocalCache.get(key);
        if (null != userInfo) {
            threadLocal.set(userInfo);
            log.info("本地缓存有效，userCode={}", userInfo.getAccount());
            return;
        }
        try {
            log.info("①开始调Oauht-Auth接口验证Token");
            ResultBean<UserDetailsVO> response = authService.getUserInfo(token);
            log.info("②验证Token返回结果={}", response.getResponseMsg());
            if (response.getIsSuccess()) {
                userInfo = response.getData();
                log.info("③验证Token返回结果解析完成，userCode={}", userInfo.getAccount());
                LocalCache.put(key, userInfo, 5000L);
                threadLocal.set(userInfo);
            } else {
                throw new RuntimeException(AuthorityEnum.TOKEN_NOT_BLANK.getMessage());
            }
        }  catch (Exception e) {
            log.error("验证Token失败②", e);
            throw e;
        }
    }
    public static UserDetailsVO getUserInfo() {
        return (UserDetailsVO)threadLocal.get();
    }

    public static void destroy() {
        threadLocal.remove();
    }

    public static void logout(String token) {
        LocalCache.remove(KEY_PREF + token);
    }
}
